package pac1_rgr;

import process.Dispatcher;
import queues.QueueForTransactions;
import qusystem.MultiActor;
import stat.DiscretHisto;
import transProcess.ITransProcesable;
import widgets.experiments.IExperimentable;




public class Model implements IExperimentable, ITransProcesable{
	private Main gui;
	private Dispatcher dispatcher;
	private TimeTimer2 time;
	private QueueForTransactions queueOfCars;
	private QueueForTransactions queueOfWorkers_outTime;
	private GenerCar1 generCar1;
	private MultiActor multiWorker;
	private DiscretHisto discretHisto;
	private double sum;
	private double lastSumTime;
	private double accumTime;
	
	public Model(Dispatcher d, Main g) {
		if (d == null || g == null) {
			System.out.println("Не визначено диспетчера або GUI для Model");
			System.out.println("Подальша робота неможлива");
			System.exit(0);
		}
		dispatcher = d;
		gui = g;
		dispatcher.printToProtocol("Model is created");
		// Передаємо акторів до стартового списку диспетчера
		componentsToStartList();

	}
	
	public Dispatcher getDispatcher() {
		if(dispatcher==null){
			System.out.println("Не визначено диспетчера для моделі");
		}
		return dispatcher;
	}
	public void componentsToStartList() {
		// Передаємо акторів диспетчеру
		dispatcher.addStartingActor(getGenerCar1());
		dispatcher.addStartingActor(getMultiWorker());
		dispatcher.addStartingActor(getTimeTimer2());
	}
	
	public TimeTimer2 getTimeTimer2() {
		if (time == null) {
			time = new TimeTimer2("Timer ", gui, this);
		}
		return time;
	}
	
	GenerCar1 getGenerCar1() {
		if (generCar1 == null) {
			generCar1 = new GenerCar1("Генератор вантажівок", gui, this);
		}
		return generCar1;
	}

	public QueueForTransactions getQueueOfCars() {
		if (queueOfCars == null) {
			queueOfCars = new QueueForTransactions();
			queueOfCars.setNameForProtocol("Черга вантажівок");
			queueOfCars.setDispatcher(dispatcher);
		}
		return queueOfCars;
	}
	
	public QueueForTransactions getQueueTimeWork() {
		if (queueOfWorkers_outTime == null) {
			queueOfWorkers_outTime = new QueueForTransactions();
			queueOfWorkers_outTime.setNameForProtocol("Черга yy");
			queueOfWorkers_outTime.setDispatcher(dispatcher);
		}
		return queueOfWorkers_outTime;
	}
	
	public MultiActor getMultiWorker() {
		if (multiWorker == null) {
			multiWorker = new MultiActor();
			multiWorker.setNumberOfClones(gui.getChooseDataWorkers().getInt());
			multiWorker.setOriginal(new Workers("Бригада ", this.gui, this));
		}
		return multiWorker;
	}
	
	public DiscretHisto getDiscretHisto3() {
		if (discretHisto == null) {
			discretHisto = new DiscretHisto();
		}
		return discretHisto;
	}
	public void initForTest() {			
		getQueueOfCars().setPainter(gui.getDiagramQueueCars().getPainter());	
		getQueueTimeWork().setPainter(gui.getDiagramTimeWork().getPainter());
	}

	public void initForStat() {	
		gui.getHisto1().initFromTo(1,5,5);
		gui.getDiscretHisto().initFromTo(0,500);
		dispatcher.setProtocolFileName("");
	}
	
	
	public void initForExperiment(double finishTime, double factor) {

		getMultiWorker().setNumberOfClones((int) factor);
		//getDispatcher().setProtocolFileName("");
		//gui.getChooseRandomCar1().setToolTipText(String.valueOf((int) factor));
		getQueueOfCars().init();
		getQueueTimeWork().init();
		getQueueOfCars().setPainter(null);
		getQueueTimeWork().setPainter(null);
		gui.getChooseDataModelTime().setText(String.valueOf(finishTime));
		gui.getChooseDataWorkers().setText(String.valueOf(factor));
		if (gui.getJRadioButton().isSelected()){
			getQueueOfCars().setDiscretHisto(getDiscretHisto3());
			getDiscretHisto3().init();
		} else
		{
			getQueueTimeWork().setDiscretHisto(getDiscretHisto3());
			getDiscretHisto3().init();
		}

	}
	
	@Override
	public double getResultOfExperiment() {
		
		return getDiscretHisto3().getAverage();
	}
	@Override
	public double getTransResult() {
		if (gui.getJRadioButton2().isSelected()) {
			double dt = getDispatcher().getCurrentTime() - lastSumTime;
			lastSumTime = getDispatcher().getCurrentTime();
			sum += dt * getQueueOfCars().size();
			accumTime += dt;
			return sum / accumTime;
		}
		else {
			double dt = getDispatcher().getCurrentTime() - lastSumTime;
			lastSumTime = getDispatcher().getCurrentTime();
			sum += dt * getQueueTimeWork().size();
			accumTime += dt;
			return sum / accumTime;
		}
	}


	@Override
	public void initForTrans(double d) {		
		gui.getChooseDataModelTime().setText(String.valueOf(d)); // время моделлирования
		int modelID = hashCode();
		// Ініціалізуємо  купу
		getQueueOfCars().init();
		getQueueOfCars().setNameForProtocol("Черга автомобілів" + modelID);		
		// Ініціалізуємо чергу до навантажувача 
		getQueueTimeWork().init();
		getQueueTimeWork().setNameForProtocol("Черга бригад, що працюють понаднормово" + modelID);
		// Динамічна індикація черг не потрібна
		getQueueTimeWork().setPainter(null);
		getQueueOfCars().setPainter(null);	
		getMultiWorker().setNumberOfClones(gui.getChooseDataWorkers().getInt());
	
		
	}

	@Override
	public void resetTransAccum() {
		lastSumTime = getDispatcher().getCurrentTime();
		sum = 0;
		accumTime = 0;
		
	}
/*	public Workers getWorkers() {
	if (workers == null) {
		workers = new Workers("Бригади ", gui, this);
	}
	return workers;
}

public Car car() {
	if (car == null) {
		car = new Car("Вантажівки ", gui, this);
	}
	return car;
} 	
public QueueForTransactions getQueueOfWorkers() {
	if (queueOfWorkers == null) {
		queueOfWorkers = new QueueForTransactions();
		queueOfWorkers.setNameForProtocol("Черга бригад");
		queueOfWorkers.setDispatcher(dispatcher);
	}
	return queueOfWorkers;
}
*/

}
